#pragma once
#include "PoolMgr.h"
namespace Lumin {
namespace Win32 {

template<class T>
	class CWriteAdaptor;
template<class T>
	class CReadAdaptor;

template<class T>
	class CRWQueue
{
private:
	struct ListNode : public CCounter
	{
		T data;
		ListNode* next;
		static void *operator new(size_t objSize)
		{
			return CPoolMgr<CRWQueue<T>::ListNode>::GetInstance()->Allocate(objSize);
		}
		static void operator delete(void *pObject, size_t bufferSize)
		{
			CPoolMgr<CRWQueue<T>::ListNode>::GetInstance()->Free(pObject);
		}
		ListNode():next(0)
		{

		}
		explicit ListNode(ListNode* pNode):next(pNode)
		{ 
		}
	};
public:
	CRWQueue():beg(new ListNode(0)),end(beg)
	{
	}
	~CRWQueue()
	{
		if(beg != NULL){
			delete beg;
			beg = NULL;
		}
		CPoolMgr<CRWQueue<T>::ListNode>::Release();
	}
private:
	friend CWriteAdaptor<T>;
	friend CReadAdaptor<T>;
	ListNode* beg;
	ListNode* end;
private:
	bool empty()
	{
		return beg == end;
	}
	void push_back(T data)
	{ 
		end->data = data;
		end->next = new ListNode(0);
		end = end->next;
	}
	T front()
	{
		return beg->data;
	}
	void pop_front() 
	{ 
		if(!empty())
		{
			ListNode* old = beg;
			beg = beg->next;
			delete old;
		}
	}
};

template<class T>
	class CWriteAdaptor
{
private:
	CRWQueue<T>& m_queue;
public:
	CWriteAdaptor(CRWQueue<T>& que):m_queue(que){}
	void push_back(T data) { m_queue.push_back(data); }
};

template<class T>
	class CReadAdaptor
{
private:
	CRWQueue<T>& m_queue;
public:
	CReadAdaptor(CRWQueue<T>& que): m_queue(que){}
	void pop_front() { m_queue.pop_front(); }
	T front() { return m_queue.front(); }
	bool empty() { return m_queue.empty(); }
};


}
}